/*
 * @Author: 大旗云业务部-黄龙
 * @Date: 2023-08-22 15:17:17
 * @LastEditors: Kou Jing（koujing@daqsoft.com）
 * @LastEditTime: 2023-12-15 11:23:48
 * @Description: 公共HTTP请求
 */
import axios, {
	type AxiosInstance,
	type AxiosRequestConfig,
	type AxiosError,
	type AxiosPromise,
	type AxiosResponse
} from 'axios';
import { errorToast, responseErrorHandler, responseHandler } from './response-handler';
import type { IRequest } from './common';
import { useUserInfoStore } from '@/stores/modules/user-info';
import { showLoadingToast, type ToastWrapperInstance } from 'vant';

// 当前环境信息
const env = import.meta.env;
// 加载提示实例
let loadingInstance: ToastWrapperInstance | null = null;
// 加载提示次数
let loadingCount: number = 0;

// 显示加载，每次请求次数加1
const showLoading = () => {
	// 没有实例时创建加载实例
	if (loadingCount === 0) {
		loadingInstance = showLoadingToast({
			duration: 0,
			forbidClick: true,
			message: '加载中'
		});
	}
	loadingCount++;
};

// 根据次数隐藏加载，每次调用次数减1
const hiddenLoading = () => {
	loadingCount--;
	if (loadingCount <= 0 && loadingInstance) {
		loadingCount = 0;
		loadingInstance.close();
	}
};

class Request implements IRequest {
	private service: AxiosInstance;
	// 请求实例
	constructor(config: AxiosRequestConfig) {
		// 创建axios实例
		this.service = axios.create(config);
		// 请求拦截
		this.requestInterceptors();
		// 请求响应拦截
		this.responseInterceptors();
	}

	// 请求拦截：添加token
	private requestInterceptors() {
		this.service.interceptors.request.use(
			(config) => {
				showLoading();
				const userInfo = useUserInfoStore();
				const token = userInfo.token;
				const encryptionType = userInfo.encryptionType;
				// config.headers.JSESSIONID = '3551ebf82337477b8e6ca417f3df9501';
				if (token) {
					config.headers.JSESSIONID = token;
				}

				// 站点编码
				config.headers.siteCode = env.VITE_SITECODE;
				if (encryptionType) {
					// TODO 加密类型功能待增加（安全系统完成后）
					// const stringParams = JSON.stringify(data);
					// const encryptData = sm4Encrypt(stringParams);
					// console.log('加密前请求体：', sm4Decrypt(encryptData));
					// config.data = encryptData;
				}
				return config;
			},
			(error: AxiosError) => {
				hiddenLoading();
				errorToast('服务器异常,请联系管理员!');
				return Promise.reject(error);
			}
		);
	}

	// 请求响应拦截
	private responseInterceptors() {
		this.service.interceptors.response.use(
			(response: AxiosResponse) => {
				hiddenLoading();
				// 判断接口业务逻辑是否成功
				const result = response.data;
				if (result.success) {
					return result;
				} else {
					let errorMessage = '服务器异常,请联系管理员!';
					if (result.msg) {
						errorMessage = result.msg;
					}
					responseHandler(result, response.config.errorTip);
					return Promise.reject(new Error(errorMessage));
				}
			},
			(error) => {
				hiddenLoading();
				const err = error as AxiosError;
				const systemError = responseErrorHandler(err, error.config.errorTip);
				// 返回接口返回的错误信息
				return Promise.reject(new Error(systemError));
			}
		);
	}

	/**
	 * get请求
	 * @param url 请求地址
	 * @param params 请求参数
	 */
	public get(url: string, params?: any, errorTip = true): AxiosPromise {
		return this.service({
			errorTip,
			url,
			method: 'get',
			params
		});
	}

	/**
	 * post请求
	 * @param url 请求地址
	 * @param params 请求参数
	 */
	public post(url: string, params?: any, errorTip = true, header?: any): AxiosPromise {
		return this.service({
			errorTip,
			url,
			method: 'post',
			headers: {
				'Content-Type': 'application/json;charset=UTF-8',
				...header
			},
			data: params
		});
	}
}

export default Request;
